/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ***************************************************************************
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as 
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 *  As a special exception, you may use this file as part of a free software
 *  library without restriction.  Specifically, if other files instantiate
 *  templates or use macros or inline functions from this file, or you compile
 *  this file and link it with other files to produce an executable, this
 *  file does not by itself cause the resulting executable to be covered by
 *  the GNU General Public License.  This exception does not however
 *  invalidate any other reasons why the executable file might be covered by
 *  the GNU General Public License.
 *
 ****************************************************************************
 */
/* Author: Massimo
 * Date  : January 2014
 *
 */
/*        -----
 *       |     |
 *       |  W  | ----
 *        -----      |
 *          .        |       -----
 *          .        |----> |     |
 *          .        |      |  S  |
 *        -----      |       -----
 *       |     |-----
 *       |  W  |
 *        -----
 *
 *   2-stage pipeline: 
 *     - the first stage is a farm with no Emitter and Collector
 *     - the second stage is a multi-input node
 *
 */

#include <ff/ff.hpp>

using namespace ff;
long const int NUMTASKS=10;


struct W: ff_node {
    void *svc(void*) {
        for(long i=(get_my_id()+1); i<=NUMTASKS; ++i)
            ff_send_out((void*)i);
        return NULL;
    }
};

struct Stage: ff_minode {
    void *svc(void *task) { 
        printf("received %ld from %zd\n", (long)task, get_channel_id());
        return GO_ON;
    }
};


int main() {
#if 0
    Stage S;
    std::vector<ff_node*> w;
    w.push_back(new W);
    w.push_back(new W);
    w.push_back(new W);
    ff_farm farm(w);
    farm.remove_collector();
    ff_pipe<long> pipe(&farm,&S);
    pipe.run_and_wait_end();

#else
    Stage S;
    ff_farm farm;
    std::vector<ff_node*> w;
    w.push_back(new W);
    w.push_back(new W);
    w.push_back(new W);
    farm.add_workers(w);
    farm.remove_collector();

    ff_pipeline pipe;
    pipe.add_stage(&farm);
    pipe.add_stage(&S);

    pipe.run_and_wait_end();
#endif

    printf("DONE\n");
    return 0;
}
